package com.zhiyun.yycall;

import java.util.ArrayList;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.atomic.AtomicBoolean;

import android.content.Context;
import android.content.Intent;
import android.graphics.PixelFormat;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Handler;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.WindowManager;
import android.view.WindowManager.LayoutParams;
import android.widget.TextView;

import com.gzit.utils.AndroidUtils;
import com.gzit.utils.StringUtils;
import com.zhiyun.message.HangupCallRequest;
import com.zhiyun.message.HangupCallResponse;
import com.zhiyun.message.QueryCallStatusRequest;
import com.zhiyun.message.QueryCallStatusResponse;
import com.zhiyun.message.StartCallRequest;
import com.zhiyun.message.StartCallResponse;
import com.zhiyun.net.AsynCallback;
import com.zhiyun.net.Net;
import com.zhiyun.net.Response;
import com.zhiyun.store.CallLogItem;
import com.zhiyun.trace.TraceActivity;

public class YYCallController {

	// 呼叫状态轮询的间隔
	public static final int POLLING_STATUS_INTERVAL = 5 * 1000;

	public static String MESSAGE_ACTION = "com.qianzhu.callbackuu.msg.action";

	private StartCallRequest request;
	private long callbackBeginTime = -1;
	private YYCallScreen screen;
	private AtomicBoolean stopped = new AtomicBoolean(false);
	private String controllerId;
	private Timer timer;

	private Handler mainHandler;
	private Context context;

	// TC:什么时候回收控制ID
	private static ArrayList<YYCallController> controllers = new ArrayList<YYCallController>();

	public static YYCallController getController(String controllerId) {

		synchronized (controllers) {
			for (YYCallController c : controllers) {
				if (c.controllerId.equals(controllerId)) {
					return c;
				}

			}
		}
		return null;
	}

	private YYCallController() {
		screen = new YYCallScreen();
	}

	public static YYCallController createController(Context context) {

		synchronized (controllers) {
			if (!controllers.isEmpty()) {
				for (YYCallController controller : controllers) {
					controller.stopCallback();
				}
				// 取消掉前一个控制器并删除掉排在最前的控制器,只保留最多是个的控制器在内存中
				if (controllers.size() > 5) {
					controllers.remove(0);
				}

			}

			// 创建新的控制器
			YYCallController controller = new YYCallController();
			controller.context = context;
			controller.mainHandler = new Handler(context.getMainLooper());
			// 创建控制器ID
			controller.controllerId = "" + System.currentTimeMillis();
			controllers.add(controller);

			return controller;
		}
	}

	public static YYCallController getLateastController() {

		synchronized (controllers) {
			if (controllers.isEmpty()) {
				return null;
			}
			return controllers.get(controllers.size() - 1);
		}

	}

	public String getControllerId() {
		return controllerId;
	}

	public boolean isStoped() {
		return stopped.get();
	}

	// 发出回拨请求
	public void startCallback(final String phoneNo) {

		// 呼出时是否满足回拨的条件
		if (!callOutInYYCallMode(phoneNo)) {
			AndroidUtils.toastShort("回拨条件不满足，无法发起回拨");
			this.stopCallback();
			return;
		}

		// 直接发出回拨请求
		sendMsg(String.format("正在发送拨号请求 %s \n当前为云之呼省钱模式...", phoneNo));

		request = new StartCallRequest();
		request.setPhoneNo(Config.getPhoneNo());
		request.setPassword(Config.getPassword());
		request.setTargetNo(phoneNo);

		callbackBeginTime = System.currentTimeMillis();

		Net.doSimpleHttpRemoter(request, new StartCallResponse(),
				new AsynCallback<Response>() {

					@Override
					public boolean callback(Response r) {

						if (isStoped()) {
							return false;
						}

						if (!r.isOk()) {
							sendMsg("拨号请求发送失败，可以选择切换为正常拨号模式");
							stopCallback();

							// TD：显示正常拨号模式的按钮
							// TD: 轮询到失败的状态后，也需要显示正常拨号按钮？

							return true;
						}

						String targetPhoneNo = request.getTargetNo();

						sendMsg(String.format("拨号请求已发送 \n等待%s响应...",
								targetPhoneNo));

						// 轮询拨号状态
						startPollCallingStatus(context);

						// 异步记录本次的拨号记录
						storeCallHistory(context, targetPhoneNo);

						return true;
					}
				});

		// 通过广播发出回拨请求：在要拦截外呼电话，并转化为回拨请求的时候有用
		// Intent intent = new Intent();
		// intent.setAction(Config.ACTION_CALL);
		// intent.putExtra("call_from_app", true);
		// intent.putExtra("phoneNo", phoneNo);
		// ctx.sendBroadcast(intent);

	}

	// 停止回拨

	public void stopCallback() {
		stopped.set(true);
		hideYYCallWindowImediatlly();
		stopPollCallingStatus();

	}

	// 挂断呼叫
	public void hangupCall(Context ctx) {

		stopCallback();

		HangupCallRequest req = new HangupCallRequest();
		req.setPhoneNo(request.getPhoneNo());
		req.setCallId(request.getCallId());
		req.setPassword(Config.getPassword());

		Net.doSimpleHttpRemoter(req, new HangupCallResponse(),
				new AsynCallback<Response>() {
					@Override
					public boolean callback(Response r) {
						return true;
					}
				});

	}

	// 决策是否能够自动接通，是否可以走回拨的逻辑
	public boolean canAutoAnswer(String incomingPhone) {
		if (isStoped()) {
			return false;
		}

		// 本机号码未来取得
		if (StringUtils.isBlank(Config.getPhoneNo())) {
			return false;
		}

		// 超过一分钟才振铃，说明本次回拨可能已经失败了
		if (System.currentTimeMillis() - callbackBeginTime > 30 * 1000) {
			return false;
		}

		// 号码没有透传，传递的进来的号码应该是null值，非回拨的不能拦截自动接听
		if (!StringUtils.isBlank(incomingPhone)) {
			if (StringUtils.isAllNotBlank(getTargetNo())
					&& getTargetNo().equals(incomingPhone)) {// 拨打进来的号码恰好是回拨号码，则照样接通
				return true;

			}
			return false;
		}

		return true;

	}

	private void storeCallHistory(final Context ctx, final String phoneNo) {
		new AsyncTask<String, Integer, Boolean>() {

			@Override
			protected Boolean doInBackground(String... params) {
				CallLogItem item = new CallLogItem();
				item.callTime = System.currentTimeMillis();
				item.duration = 0;
				item.fromNo = Config.getPhoneNo();
				item.targetNo = phoneNo;
				item.type = CallLogItem.TYPE_OUT;

				try {
					item.store();
					Intent history = new Intent();
					history.setAction(Config.ACTION_CALLHISTORY);
					ctx.sendBroadcast(history);
				} catch (Exception e) {
					e.printStackTrace();
				}

				return null;
			}
		}.execute("");

	}

	public String getPhoneNo() {
		if (request == null) {
			return null;
		}
		return request.getPhoneNo();
	}

	public String getTargetNo() {
		if (request == null) {
			return null;
		}
		return request.getTargetNo();
	}

	public void hideYYCallWindowImediatlly() {

		this.mainHandler.post(new Runnable() {
			@Override
			public void run() {
				screen.hide();

			}
		});

	}

	public void sendMsg(final String msg) {
		if (this.isStoped()) {
			return;
		}

		this.mainHandler.post(new Runnable() {
			@Override
			public void run() {
				if (isStoped()) {
					return;
				}
				screen.show(context, msg);

			}
		});

	}

	// 开始呼叫状态轮询
	public void startPollCallingStatus(Context context) {

		timer = new Timer();
		timer.scheduleAtFixedRate(new TimerTask() {

			@Override
			public void run() {
				pollStatus();
			}
		}, 0, POLLING_STATUS_INTERVAL);

		/*
		 * AlarmManager alarmMgr = (AlarmManager) context
		 * .getSystemService(Context.ALARM_SERVICE); Intent intent = new
		 * Intent(context.getApplicationContext(), CallStatusReceiver.class);
		 * intent.putExtra("callId", request.getCallId());
		 * 
		 * int requestCode = 0; PendingIntent pendIntent =
		 * PendingIntent.getBroadcast( context.getApplicationContext(),
		 * requestCode, intent, PendingIntent.FLAG_UPDATE_CURRENT);
		 * 
		 * long triggerAtTime = SystemClock.elapsedRealtime() + 2 * 1000; int
		 * interval = 2 * 1000;
		 * alarmMgr.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
		 * triggerAtTime, interval, pendIntent);
		 */

	}

	private void pollStatus() {

		if (this.isStoped()) {
			return;
		}

		String callId = this.request.getCallId();
		QueryCallStatusRequest req = new QueryCallStatusRequest();
		req.setCallId(callId);
		req.setPhoneNo(Config.getPhoneNo());
		req.setPassword(Config.getPassword());

		Net.doSimpleHttpRemoter(req, new QueryCallStatusResponse(),
				new AsynCallback<Response>() {

					@Override
					public boolean callback(Response r) {

						if (isStoped()) {
							return false;
						}

						if (!r.isOk()) {
							stopPollCallingStatus();
							return true;
						}

						QueryCallStatusResponse resp = (QueryCallStatusResponse) r;
						switch (resp.getStatusCode()) {

						case QueryCallStatusResponse.WAITTING_CALL:
						case QueryCallStatusResponse.CONNECTING_CALL:
							sendMsg(String.format("云之呼正在连接%s\n...",
									getTargetNo()));
							break;

						case QueryCallStatusResponse.CONNECTED:// 连接成功

							sendMsg(String.format("云之呼成功接通%s\n对方振铃中...",
									getTargetNo()));

							break;

						case QueryCallStatusResponse.BALANCE_NOT_ENOGHT:
							sendMsg("你的云之呼余额不足");
							stopPollCallingStatus();
							break;

						case QueryCallStatusResponse.BCALL_BUSY:
							sendMsg("拨打的号码正忙");
							stopPollCallingStatus();
							break;

						case QueryCallStatusResponse.BCALL_HANDOFF:
							sendMsg("拨打的号码挂断");
							stopPollCallingStatus();
							break;

						case QueryCallStatusResponse.BCALL_REFUSED:
							sendMsg("拨打的号码拒绝");
							stopPollCallingStatus();
							break;

						case QueryCallStatusResponse.BCALL_NO_ERROR:
							sendMsg("拨打的号码无法接通");
							stopPollCallingStatus();
							break;

						case QueryCallStatusResponse.UNKNOW_ERROR:

						case QueryCallStatusResponse.ACALL_HANDOFF:

						case QueryCallStatusResponse.ACALL_REFUSED:

						case QueryCallStatusResponse.ACALL_NO_ERROR:

						case QueryCallStatusResponse.ACALL_BUSY:

						default:
							sendMsg("呼叫无法到达对方");
							stopPollCallingStatus();

						}
						return true;
					}
				});

	}

	// 停止呼叫状态轮询
	public void stopPollCallingStatus() {

		if (timer != null) {
			timer.cancel();
			timer = null;
		}

		// AlarmManager alarmMgr = (AlarmManager) context
		// .getSystemService(Context.ALARM_SERVICE);
		// Intent intent = new Intent(context.getApplicationContext(),
		// CallStatusReceiver.class);
		// PendingIntent pendIntent = PendingIntent.getBroadcast(
		// context.getApplicationContext(), 0, intent,
		// PendingIntent.FLAG_CANCEL_CURRENT);
		// alarmMgr.cancel(pendIntent);

	}

	// 决策 是否可以切换到回拨模式并显示弹窗
	private boolean callOutInYYCallMode(String outGoingPhone) {

		// 本机号码未取得
		if (StringUtils.isBlank(Config.getPhoneNo())) {
			return false;
		}

		// 网络不可用，也不能发起回拨请求
		// 由调用方确保网络是OK的
		// if (!AndroidUtils.System.isNetworkAvailable()) {
		// AndroidUtils.toastShort("貌似网络不给力，无法发起呼叫请求");
		// return false;
		// }

		return true;

	}

	// 正常拨号
	public static void startNormalCall(Context ctx, String phoneNo) {

		Intent intent = new Intent("android.intent.action.CALL",
				Uri.parse("tel:" + phoneNo));
		ctx.startActivity(intent);

	}

	// yycall屏幕
	class YYCallScreen {
		private WindowManager wm;
		private TextView messageView;

		private View contentView;

		public void show(Context ctx, String msg) {

			if (contentView == null) {
				this.createPopWindow(ctx);
			}
			messageView.setText(msg);

		}

		public void hide() {
			if (contentView != null) {
				wm.removeViewImmediate(contentView);
				// wm.removeView(contentView);
			}
			contentView = null;
		}

		// private void startAnimation() {

		// final ImageView popupTop = (ImageView) contentView
		// .findViewById(R.id.popup_top);
		// contentView.post(new Runnable() {
		//
		// @Override
		// public void run() {
		// AnimationDrawable anim = (AnimationDrawable) popupTop
		// .getBackground();
		// anim.start();
		//
		// }
		// });

		// }

		// private void stopAnimation() {

		// final ImageView popupTop = (ImageView) contentView
		// .findViewById(R.id.popup_top);
		// contentView.post(new Runnable() {
		//
		// @Override
		// public void run() {
		// AnimationDrawable anim = (AnimationDrawable) popupTop
		// .getBackground();
		//
		// anim.stop();
		//
		// }
		// });
		// }

		private void createPopWindow(final Context ctx) {

			Log.i("yycall", "getWindowManager begin...");

			long begin = System.currentTimeMillis();
			wm = (WindowManager) ctx.getApplicationContext().getSystemService(
					Context.WINDOW_SERVICE);

			long end = System.currentTimeMillis();
			Log.i("yycall", "getWindowManager end:" + (end - begin));

			WindowManager.LayoutParams params = new WindowManager.LayoutParams();
			// params.type = WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY;
			// params.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
			// | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;

			// 以屏幕左上角为原点，设置x、y初始值
			params.x = 0;
			params.y = 0;

			params.type = LayoutParams.TYPE_PHONE;
			params.width = WindowManager.LayoutParams.FILL_PARENT;
			params.height = WindowManager.LayoutParams.FILL_PARENT;

			params.format = PixelFormat.RGBA_8888;

			Log.i("yycall", "inflater begin...");

			begin = System.currentTimeMillis();

			contentView = LayoutInflater.from(ctx).inflate(
					R.layout.yycall_popup_window, null);

			end = System.currentTimeMillis();
			Log.i("yycall", "inflater end:" + (end - begin));

			messageView = (TextView) contentView.findViewById(R.id.content);

			// Log.i("yycall", "set animation begin...");
			// begin = System.currentTimeMillis();

			// final ImageView popupTop = (ImageView) contentView
			// .findViewById(R.id.popup_top);
			// popupTop.setBackgroundResource(R.anim.popup_top_anim);
			// startAnimation();

			// end = System.currentTimeMillis();
			// Log.i("yycall", "set animation end:" + (end - begin));

			contentView.findViewById(R.id.end_call_btn).setOnClickListener(
					new OnClickListener() {

						@Override
						public void onClick(View v) {

							TraceActivity.traceEvent(ctx, "hangoff");
							hangupCall(ctx);

						}
					});

			Log.i("yycall", "add view  begin...");
			begin = System.currentTimeMillis();

			wm.addView(contentView, params);

			end = System.currentTimeMillis();
			Log.i("yycall", "add view end:" + (end - begin));
		}

	}

}
